[libcxx] Fix max_size() across all containers Summary: The `max_size()` method of containers should respect both the allocator's reported `max_size` and the range of the `difference_type`. This patch makes all containers choose the smallest of those two values. Reviewers: mclow.lists, EricWF Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D26885 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@287729 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/__hash_table b/include/__hash_table index 3072f93..0dc188b 100644 --- a/include/__hash_table +++ b/include/__hash_table 
@@ -1004,8 +1004,11 @@  _LIBCPP_INLINE_VISIBILITY  size_type max_size() const _NOEXCEPT  { - return allocator_traits<__pointer_allocator>::max_size( - __bucket_list_.get_deleter().__alloc()); + return std::min<size_type>( + allocator_traits<__pointer_allocator>::max_size( + __bucket_list_.get_deleter().__alloc()), + numeric_limits<difference_type >::max() + );  }    pair<iterator, bool> __node_insert_unique(__node_pointer __nd); @@ -1192,7 +1195,7 @@    _LIBCPP_INLINE_VISIBILITY  size_type max_bucket_count() const _NOEXCEPT - {return __pointer_alloc_traits::max_size(__bucket_list_.get_deleter().__alloc());} + {return max_size(); }  size_type bucket_size(size_type __n) const;  _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT  { diff --git a/include/__tree b/include/__tree index f3f68b5..4c94fe5 100644 --- a/include/__tree +++ b/include/__tree 
@@ -1106,7 +1106,9 @@    _LIBCPP_INLINE_VISIBILITY  size_type max_size() const _NOEXCEPT - {return __node_traits::max_size(__node_alloc());} + {return std::min<size_type>( + __node_traits::max_size(__node_alloc()), + numeric_limits<difference_type >::max());}    void clear() _NOEXCEPT;   diff --git a/include/deque b/include/deque index 9c72d24..f8e0bb8 100644 --- a/include/deque +++ b/include/deque 
@@ -1310,7 +1310,9 @@  size_type size() const _NOEXCEPT {return __base::size();}  _LIBCPP_INLINE_VISIBILITY  size_type max_size() const _NOEXCEPT - {return __alloc_traits::max_size(__base::__alloc());} + {return std::min<size_type>( + __alloc_traits::max_size(__base::__alloc()), + numeric_limits<difference_type>::max());}  void resize(size_type __n);  void resize(size_type __n, const value_type& __v);  void shrink_to_fit() _NOEXCEPT; diff --git a/include/forward_list b/include/forward_list index 41b4b46..f344d2e 100644 --- a/include/forward_list +++ b/include/forward_list 
@@ -734,8 +734,11 @@  bool empty() const _NOEXCEPT  {return base::__before_begin()->__next_ == nullptr;}  _LIBCPP_INLINE_VISIBILITY - size_type max_size() const _NOEXCEPT - {return numeric_limits<size_type>::max();} + size_type max_size() const _NOEXCEPT { + return std::min<size_type>( + __node_traits::max_size(base::__alloc()), + numeric_limits<difference_type>::max()); + }    _LIBCPP_INLINE_VISIBILITY  reference front() {return base::__before_begin()->__next_->__value_;} diff --git a/include/list b/include/list index bebfff6..98843d6 100644 --- a/include/list +++ b/include/list 
@@ -571,6 +571,10 @@  {return __size_alloc_.second();}    _LIBCPP_INLINE_VISIBILITY + size_type __node_alloc_max_size() const _NOEXCEPT { + return __node_alloc_traits::max_size(__node_alloc()); + } + _LIBCPP_INLINE_VISIBILITY  static void __unlink_nodes(__link_pointer __f, __link_pointer __l) _NOEXCEPT;    _LIBCPP_INLINE_VISIBILITY @@ -904,7 +908,11 @@  bool empty() const _NOEXCEPT {return base::empty();}  _LIBCPP_INLINE_VISIBILITY  size_type max_size() const _NOEXCEPT - {return numeric_limits<difference_type>::max();} + { + return std::min<size_type>( + base::__node_alloc_max_size(), + numeric_limits<difference_type >::max()); + }    _LIBCPP_INLINE_VISIBILITY  iterator begin() _NOEXCEPT {return base::begin();} diff --git a/include/vector b/include/vector index edcb7df..f5bd7d0 100644 --- a/include/vector +++ b/include/vector 
@@ -941,7 +941,8 @@  typename vector<_Tp, _Allocator>::size_type  vector<_Tp, _Allocator>::max_size() const _NOEXCEPT  { - return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()), numeric_limits<size_type>::max() / 2); // end() >= begin(), always + return _VSTD::min<size_type>(__alloc_traits::max_size(this->__alloc()), + numeric_limits<difference_type>::max());  }    // Precondition: __new_size > capacity()